/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */
#include "datetime.h"
#include "ui_datetime.h"
#include <QHBoxLayout>
#include <QDebug>
#include <QMovie>
#include <QDir>
#include <QDesktopWidget>
#include <QLineEdit>

#include <QTimeZone>
#include <QComboBox>
#include <QFrame>
#include <QLabel>
#include <locale.h>
#include <libintl.h>
#include <QProcess>
#include <qmath.h>
#include <polkit-qt5-1/polkitqt1-authority.h>
#include "widgets/ImageUtil/imageutil.h"
#include "clock.h"
#include <QButtonGroup>
#include <QCalendarWidget>
#include "widgets/Frame/hlineframe.h"
#include "customCalendar.h"
#include "interface/common.h"
#include "getsyncres.h"

const char kTimezoneDomain[] = "installer-timezones";
const char kDefaultLocale[]  = "en_US.UTF-8";

const QString kcnBj =           "北京";
const QString kenBj =           "Asia/Beijing";

#define FORMAT_SCHEMA           "org.ukui.control-center.panel.plugins"
#define TIME_FORMAT_KEY         "hoursystem"
#define DATE_KEY                "date"
#define NTP_KEY                 "ntp"
#define TIMEZONES_KEY           "timezones"
#define MAX_TIMES               5

#define STYLE_FONT_SCHEMA  "org.ukui.style"

const QStringList linkShanghaiTzList = {
    "Asia/Beijing",
    "Asia/Urumqi"
};

const QStringList ntpAddressList = {
                            "pool.ntp.org",
                            "cn.ntp.org.cn",
                            "cn.pool.ntp.org",
                            "ntp.aliyun.com",

                            "0.debian.pool.ntp.org",
                            "1.debian.pool.ntp.org",

                            "0.arch.pool.ntp.org",
                            "1.arch.pool.ntp.org",

                            "0.fedora.pool.ntp.org",
                            "1.fedora.pool.ntp.org",

                          };

DateTime::DateTime()
    : mFirstLoad(true),
    m_checkedId(0)
{
    pluginName = tr("Date");
    pluginType = DATETIME;
}

DateTime::~DateTime()
{
    if (syncThread) {
        syncThread->disconnect();
        syncThread->terminate();
        syncThread->quit();
        syncThread->wait();
        delete syncThread;
        syncThread = nullptr;
    }
    if (!mFirstLoad) {
        delete ui;
        delete m_zoneinfo;
        ui         = nullptr;
        m_zoneinfo = nullptr;
    }
}

QString DateTime::plugini18nName()
{
    return pluginName;
}

int DateTime::pluginTypes()
{
    return pluginType;
}

QWidget *DateTime::pluginUi()
{
    if (mFirstLoad) {  
        pluginWidget = new QWidget;
        mFirstLoad = false;
        ui = new Ui::DateTime;
        pluginWidget->setAttribute(Qt::WA_DeleteOnClose);
        ui->setupUi(pluginWidget);
        initUI();
        initTitleLabel();
        initStatus();
        initComponent();
        initConnect();
        connectToServer();
        initTimeShow();
        if (Common::isTablet()) {
            settingForIntel();
        }
    } else {
        fillTimeCombox(m_formTimeBtn->isChecked());
    }

    return pluginWidget;
}

const QString DateTime::name() const
{

    return QStringLiteral("Date");
}

bool DateTime::isShowOnHomePage() const
{
    return true;
}

QIcon DateTime::icon() const
{
    if (QIcon::hasThemeIcon("ukui-datetime-symbolic")) {
        return QIcon::fromTheme("ukui-datetime-symbolic");
    }
    return QIcon::fromTheme("ukui-datetine-symbolic");  //主题命名错误，兼容
}

bool DateTime::isEnable() const
{
    return true;
}

void DateTime::initTitleLabel()
{
    QGSettings *m_fontSetting = new QGSettings("org.ukui.style");
    QFont font;
    //~ contents_path /Date/Current Date
    ui->titleLabel->setText(tr("Current Date"));
    ui->titleLabel_2->adjustSize();
    //~ contents_path /Date/Other Timezone
    ui->titleLabel_2->setText(tr("Other Timezone"));
    timeClockLable->setObjectName("timeClockLable");
    if (QLocale::system().amText() == "སྔ་དྲོ་") {
        font.setPixelSize(m_fontSetting->get("systemFontSize").toInt() * 20 / 11);
    } else {
        font.setPixelSize(m_fontSetting->get("systemFontSize").toInt() * 28 / 11);
    }
    font.setWeight(QFont::Medium);
    font.setBold(true);
    timeClockLable->setFont(font);
    timeClockLable->setAlignment(Qt::AlignVCenter);
    delete m_fontSetting;
    m_fontSetting = nullptr;
}

void DateTime::initUI()
{
    m_formTimeBtn       = new KSwitchButton(pluginWidget);
    //~ contents_path /Date/24-hour clock
    m_formTimeLabel     = new QLabel(tr("24-hour clock"), pluginWidget);

    syncNetworkRetLabel = new FixLabel(pluginWidget);
    syncNetworkRetLabel->setStyleSheet("QLabel{color: #D9F82929;}");
    m_zoneinfo          = new ZoneInfo;
    m_timezone          = new TimeZoneChooser(pluginWidget);
    m_itimer            = new QTimer(this);
    m_itimer->start(1000);
    initCurrentDate();
    ui->showFrame->setOneRadiusStyle(UkccFrame::BorderRadiusStyle::Top);
    ui->showFrame->setLastRadiusStyle(UkccFrame::BorderRadiusStyle::None);

    int timezone_x = pluginWidget->topLevelWidget()->x() + (pluginWidget->topLevelWidget()->width() - 960)/2;
    int timezone_y = pluginWidget->topLevelWidget()->y() + (pluginWidget->topLevelWidget()->height() - 640)/2;
    timezone_x = timezone_x > 0 ? timezone_x : 0;
    timezone_y = timezone_y > 0 ? timezone_y : 0;

    m_timezone->move(timezone_x, timezone_y);


    ui->frame_7->adjustSize();

    for (int m = 0; m < 60; m++) {
        minComboBox->addItem(QString::number(m));
    }

    for (int s = 0; s < 60; s++) {
        secComboBox->addItem(QString::number(s));
    }

    for (int h = 0; h < 24; h++){
        hourComboBox->addItem(QString::number(h));
    }

    const QByteArray id(FORMAT_SCHEMA);
    if (QGSettings::isSchemaInstalled(id)) {
        const QByteArray id(FORMAT_SCHEMA);
        m_formatsettings = new QGSettings(id, QByteArray(), this);
        connect(m_formatsettings, &QGSettings::changed, this, [=](QString key) {
            Q_UNUSED(key);
            QString hourFormat = m_formatsettings->get(TIME_FORMAT_KEY).toString();
            bool status = ("24" != hourFormat ? false : true);
            timeFormatClickedSlot(status, true);
        });
    }

    // 初始化dbus
    m_datetimeiface       = new QDBusInterface("org.freedesktop.timedate1",
                                       "/org/freedesktop/timedate1",
                                       "org.freedesktop.timedate1",
                                       QDBusConnection::systemBus(), this);

    m_datetimeiproperties = new QDBusInterface("org.freedesktop.timedate1",
                                             "/org/freedesktop/timedate1",
                                             "org.freedesktop.DBus.Properties",
                                             QDBusConnection::systemBus(), this);

    m_ukccIfc             = new QDBusInterface("com.control.center.qt.systemdbus",
                                               "/",
                                               "com.control.center.interface",
                                               QDBusConnection::systemBus());

    initNtp();
}

void DateTime::initComponent()
{
    timeClockLable->setContentsMargins(0,0,0,0);

    //~ contents_path /Date/Change time zone
    chgzonebtn->setText(tr("Change timezone"));

    ui->hourFrame->setVisible(false);  //移到area里面了
    QHBoxLayout *hourLayout = new QHBoxLayout(ui->hourFrame);

    hourLayout->addWidget(m_formTimeLabel);
    hourLayout->addWidget(m_formTimeBtn);

    autoRadioButton->adjustSize();
    manualRadioButton->adjustSize();
    //~ contents_path /Date/Sync Time
    autoRadioButton->setText(tr("Sync Time"));
    //~ contents_path /Date/Manual Time
    manualRadioButton->setText(tr("Manual Time"));

    timeGroupBtn = new QButtonGroup(this);
    timeGroupBtn->addButton(autoRadioButton, 0);
    timeGroupBtn->addButton(manualRadioButton, 1);
    connect(timeGroupBtn, QOverload<int>::of(&QButtonGroup::buttonClicked), this, [=](int id){
        if (id != m_checkedId) {
            m_checkedId = id;
            if (id == 0) {
                synctimeFormatSlot(true, true);
                Common::buriedSettings(name(), autoRadioButton->text(), QString("clicked"));
            } else {
                synctimeFormatSlot(false, true);
                syncNetworkRetLabel->setText("");
                Common::buriedSettings(name(), manualRadioButton->text(), QString("clicked"));
            }
        }
    });

    QString timeAndWeek = getTimeAndWeek(current);
    QTimeZone localTimezone = QTimeZone(localZone.toLatin1().data());

    int utcOff = localTimezone.offsetFromUtc(QDateTime::currentDateTime())/3600;
    QString gmData;
    if (utcOff >= 0) {
        gmData = QString("(GMT+%1:%2)").arg(utcOff, 2, 10, QLatin1Char('0')).arg(utcOff / 60, 2, 10, QLatin1Char('0'));
    } else {
        gmData = QString("(GMT%1:%2)").arg(utcOff, 3, 10, QLatin1Char('0')).arg(utcOff / 60, 2, 10, QLatin1Char('0'));
    }
    dateLabel->setText(timeAndWeek + "  " + gmData + " " + localizedTimezone);

    const QByteArray styleID(STYLE_FONT_SCHEMA);
    if (QGSettings::isSchemaInstalled(styleID)) {
        QGSettings *stylesettings = new QGSettings(styleID, QByteArray(), this);
        connect(stylesettings , &QGSettings::changed, this, [=](const QString &key) {
             if("systemFont" == key || "systemFontSize" == key) {
                 QString timeAndWeek = getTimeAndWeek(current);
                 QTimeZone localTimezone = QTimeZone(localZone.toLatin1().data());

                 int utcOff = localTimezone.offsetFromUtc(QDateTime::currentDateTime())/3600;
                 QString gmData;
                 if (utcOff >= 0) {
                     gmData = QString("(GMT+%1:%2)").arg(utcOff, 2, 10, QLatin1Char('0')).arg(utcOff / 60, 2, 10, QLatin1Char('0'));
                 } else {
                     gmData = QString("(GMT%1:%2)").arg(utcOff, 3, 10, QLatin1Char('0')).arg(utcOff / 60, 2, 10, QLatin1Char('0'));
                 }
                 dateLabel->setText(timeAndWeek + "  " + gmData + " " + localizedTimezone);
             }
        });
    }

    mPreDate = timeAndWeek + "  " + gmData + " " + localizedTimezone;
    QFile tzfile("://zoneUtc");
    if (!tzfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
         qDebug("TZ File Open Failed");
    } else {
        QTextStream txt(&tzfile);
        int index = 0;
        while (!tzfile.atEnd()) {
            QStringList lineList = txt.readLine().split("\t");
            tzindexMapEn.insert(lineList.at(0),index);
            tzindexMapCN.insert(lineList.at(1),index);
            index++;
        }
    }
    tzfile.close();
}

void DateTime::initStatus()
{
    // 时区
    const QString locale = QLocale::system().name();
    QDBusReply<QVariant> tz = m_datetimeiproperties->call("Get", "org.freedesktop.timedate1", "Timezone");
    localZone = tz.value().toString();
    localizedTimezone = getLocalTimezoneName(getShowtz(localZone), locale);
    loadHour();
}


void DateTime::initTimeShow()
{
    addTimeBtn = new AddButton(this->pluginWidget, UkccFrame::BorderRadiusStyle::Around);
    ui->addLayout->addWidget(addTimeBtn);
    connect(addTimeBtn,&AddBtn::clicked,this,[=](){
        changeZoneFlag = false;
        changezoneSlot(1);
    });

    if (m_formatsettings->keys().contains(TIMEZONES_KEY)) {
        timezonesList = m_formatsettings->get(TIMEZONES_KEY).toStringList();

        int timesNum = timezonesList.size();
        if (timezonesList.size() >= MAX_TIMES) {
            timesNum = MAX_TIMES;
            ui->addFrame->setEnabled(false);
            for (int i = MAX_TIMES; i < timezonesList.size(); ++i) {
                timezonesList.removeLast();
            }
            m_formatsettings->set(TIMEZONES_KEY, timezonesList);
        }

        for (int i = 0; i < timesNum; ++i) {
            newTimeshow(timezonesList[i]);
        }
     }
}

void DateTime::addTimezone(const QString &timezone)
{
    for (int i = 0; i < timezonesList.size(); ++i) {
        if (timezonesList[i] == timezone) {
            return;
        } else if (i == timezonesList.size() - 1) {
            break;
        }
    }
    timezonesList.append(timezone);
    if (timezonesList.size() >= MAX_TIMES) {
        ui->addFrame->setEnabled(false);
    }
     if (m_formatsettings->keys().contains(TIMEZONES_KEY)) {
        m_formatsettings->set(TIMEZONES_KEY, timezonesList);
     }
    newTimeshow(timezone);
}

void DateTime::newTimeshow(const QString &timezone)
{
    TimeBtn *timeBtn = nullptr;
    if (linkShanghaiTzList.contains(timezone)) {
        timeBtn = new TimeBtn("Asia/Shanghai",timezone);
    } else {
        timeBtn = new TimeBtn(timezone);
    }
    addTimeBtn->setRadiusType(UkccFrame::BorderRadiusStyle::Bottom);
    ui->showFrame->addWidget(timeBtn);
    timeBtn->updateTime(m_formTimeBtn->isChecked());
    connect(timeBtn->deleteBtn, &QPushButton::clicked, this, [=](){
       timezonesList.removeOne(timezone);
       if (m_formatsettings->keys().contains(TIMEZONES_KEY)) {
           m_formatsettings->set(TIMEZONES_KEY, timezonesList);
       }
       timeBtn->close();
       if (!ui->addFrame->isEnabled() && timezonesList.size() < MAX_TIMES) {
            ui->addFrame->setEnabled(true);
       }
       if (timezonesList.size() == 0) {
           addTimeBtn->setRadiusType(UkccFrame::BorderRadiusStyle::Around);
       }
       ui->showFrame->removeWidget(timeBtn);
       ui->showFrame->updateShape();
    });

    connect(m_itimer, &QTimer::timeout, this, [=](){
        timeBtn->updateTime(m_formTimeBtn->isChecked());
    });
    ui->showFrame->updateShape();
}

void DateTime::initNtp()
{
    QLabel      *ntpLabel  = new QLabel(ntpFrame);
    QHBoxLayout *ntpLayout = new QHBoxLayout(ntpFrame);
                 ntpCombox = new QComboBox(ntpFrame);
    ntpLabel->setFixedWidth(135);
    ntpLayout->setContentsMargins(16,8,16,8);
    ntpFrame->setLayout(ntpLayout);
    ntpLayout->addWidget(ntpLabel);
    ntpLayout->addWidget(ntpCombox);
    //~ contents_path /Date/Sync Server
    ntpLabel->setText(tr("Sync Server"));
    ntpCombox->addItem(tr("Default"));
    ntpCombox->addItems(ntpAddressList);
    ntpCombox->addItem(tr("Customize"));

    /*自定义*/
    QLabel *ntpLabel_2 = new QLabel(ntpFrame_2);
    QHBoxLayout *ntpLayout_2 = new QHBoxLayout(ntpFrame_2);
    QLineEdit *ntpLineEdit = new QLineEdit();
    QPushButton *saveBtn = new QPushButton(ntpFrame_2);

    ntpLayout_2->setContentsMargins(16,8,26,8);
    ntpLineEdit->setParent(ntpFrame_2);
    ntpLabel_2->setText(tr("Server Address"));
    ntpLayout_2->addWidget(ntpLabel_2);
    ntpLabel_2->setFixedWidth(135);
    ntpLayout_2->addWidget(ntpLineEdit);
    ntpLayout_2->addWidget(saveBtn);
    ntpLineEdit->setPlaceholderText(tr("Required"));
    saveBtn->setText(tr("Save"));

    if (m_formatsettings->keys().contains(NTP_KEY))
        ntpLineEdit->setText(m_formatsettings->get(NTP_KEY).toString());

    connect(ntpLineEdit, &QLineEdit::textChanged, this, [=](){
        ntpLineEdit->blockSignals(true);
        while (ntpLineEdit->text().front() == " ") {
            ntpLineEdit->setText(ntpLineEdit->text().remove(0,1)); //去掉首空格
        }
        ntpLineEdit->blockSignals(false);
        saveBtn->setEnabled(!ntpLineEdit->text().isEmpty());   //为空时不允许保存
    });

    connect(saveBtn, &QPushButton::clicked, this, [=](){
        ntpLineEdit->blockSignals(true);
        while (ntpLineEdit->text().back() == " ") {
            ntpLineEdit->setText(ntpLineEdit->text().remove(ntpLineEdit->text().size()-1,1)); //去掉尾空格
        }
        ntpLineEdit->blockSignals(false);
        QString setAddr = ntpLineEdit->text();
        if (!setNtpAddr(setAddr)) {   //失败or不修改
            if (m_formatsettings->keys().contains(NTP_KEY))
                ntpLineEdit->setText(m_formatsettings->get(NTP_KEY).toString());
        } else {
            ntpComboxPreId = ntpCombox->currentIndex();
            if (m_formatsettings->keys().contains(NTP_KEY))
                m_formatsettings->set(NTP_KEY, setAddr);
        }
        Common::buriedSettings(name(), QString("ntpCombox(Customize)"), QString("setting"), ntpLineEdit->text());
    });

    const QString ntpFileName = "/etc/systemd/timesyncd.conf.d/kylin.conf";
    QFile ntpFile(ntpFileName);
    if (!ntpFile.exists()) {    //默认
        ntpCombox->setCurrentIndex(0);
        ntpFrame_2->setVisible(false);
    } else {
        QSettings readFile(ntpFileName, QSettings::IniFormat);
        QString initAddress = readFile.value("Time/NTP").toString();
        for (int i = 0; i < ntpCombox->count(); ++i) {
            if (initAddress == ntpCombox->itemText(i)) {   //是选中的
                ntpCombox->setCurrentIndex(i);
                ntpFrame_2->setVisible(false);
                break;
            } else if (i == ntpCombox->count() - 1) {     //是自定义的
                ntpCombox->setCurrentIndex(i);
                ntpLineEdit->setText(initAddress);
                ntpFrame_2->setVisible(true);
                break;
            }
        }
    }

    ntpComboxPreId = ntpCombox->currentIndex();
    connect(ntpCombox, &QComboBox::currentTextChanged, this, [=](){
        ntpCombox->hidePopup();
        qApp->processEvents();
        QString setAddr = "";
//        if (m_formatsettings->keys().contains(NTP_KEY))
//            setAddr = m_formatsettings->get(NTP_KEY).toString(); 应产品需求，每次重新选择自定义时清空
        if (ntpCombox->currentIndex() == (ntpCombox->count() - 1) && setAddr == "") { //自定义且为空
            ntpLineEdit->setText("");
            ntpFrame_2->setVisible(true);  //需要添加地址并点击保存再授权
        } else {
            if (ntpCombox->currentIndex() == 0) {  //默认
                setAddr = "default";
                ntpFrame_2->setVisible(false);
            } else if (ntpCombox->currentIndex() != ntpCombox->count() - 1) { //选择系统
                setAddr = ntpCombox->currentText();
                ntpFrame_2->setVisible(false);
            } else { //自定义且不为空
                ntpFrame_2->setVisible(true);
            }
            if (!setNtpAddr(setAddr)) {   //失败or不修改
                ntpCombox->blockSignals(true);
                ntpCombox->setCurrentIndex(ntpComboxPreId);
                ntpCombox->blockSignals(false);
                if (ntpComboxPreId == ntpCombox->count() - 1) {
                    ntpFrame_2->setVisible(true);
                    ntpLineEdit->blockSignals(true);
                    if (m_formatsettings->keys().contains(NTP_KEY)) //防止未保存的内容一直存在
                        ntpLineEdit->setText(m_formatsettings->get(NTP_KEY).toString());
                    ntpLineEdit->blockSignals(false);
                } else {
                    ntpFrame_2->setVisible(false);
                }
            } else {
                ntpComboxPreId = ntpCombox->currentIndex();
                if (m_formatsettings->keys().contains(NTP_KEY)) //防止未保存的内容一直存在
                    ntpLineEdit->setText(m_formatsettings->get(NTP_KEY).toString());
            }
            Common::buriedSettings(name(), QString("ntpCombox"), QString("select"), ntpCombox->currentText());
        }
    });
}

void DateTime::connectToServer()
{
    QThread *NetThread = new QThread;
    MThread *NetWorker = new MThread;
    NetWorker->moveToThread(NetThread);
    connect(NetThread, &QThread::started, NetWorker, &MThread::run);
    connect(NetWorker,&MThread::keychangedsignal,this,&DateTime::keyChangedSlot);
    connect(NetThread, &QThread::finished, NetWorker, &MThread::deleteLater);
    NetThread->start();
}

void DateTime::keyChangedSlot(const QString &key)
{
    if (key == "datetime") {
        initStatus();
    }
}

bool DateTime::fileIsExits(const QString &filepath)
{
    QFile file(filepath);
    if(file.exists()) {
        return true;
    } else {
        return false;
    }
}

void DateTime::datetimeUpdateSlot()
{
    setCurrentTime();

    QString timeAndWeek = getTimeAndWeek(current);
    QTimeZone localTimezone = QTimeZone(localZone.toLatin1().data());

    int utcOff = (localTimezone.offsetFromUtc(QDateTime::currentDateTime()))/3600;
    QString gmData;
    if (utcOff >= 0) {
        gmData = QString("(GMT+%1:%2)").arg(utcOff, 2, 10, QLatin1Char('0')).arg(utcOff / 60, 2, 10, QLatin1Char('0'));
    } else {
        gmData = QString("(GMT%1:%2)").arg(utcOff, 3, 10, QLatin1Char('0')).arg(utcOff / 60, 2, 10, QLatin1Char('0'));
    }
    QString currentDate = timeAndWeek + "  " + gmData + " " + localizedTimezone;

    static int widgetWidth = pluginWidget->width();
    if (mPreDate.compare(currentDate) != 0 || abs(widgetWidth - pluginWidget->width()) > 20) {

        widgetWidth = pluginWidget->width();
        mPreDate = currentDate;

        dateLabel->setText(timeAndWeek + "  " + gmData + " " + localizedTimezone);
    }
}

void DateTime::changetimeSlot()
{
    ChangtimeDialog *dialog = new ChangtimeDialog(m_formTimeBtn->isChecked(),pluginWidget);
    dialog->setWindowTitle(tr("change time"));
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    m_itimer->stop();
    m_itimer->start();
    dialog->exec();
}

void DateTime::changezoneSlot(int flag)
{
    if (flag == 1) {
        m_timezone->setTitle(tr("Add Timezone"));
    } else {
        m_timezone->setTitle(tr("Change Timezone"));
    }
    m_timezone->setWindowModality(Qt::ApplicationModal);
    int timezone_x = pluginWidget->topLevelWidget()->x() + (pluginWidget->topLevelWidget()->width() - 960)/2;
    int timezone_y = pluginWidget->topLevelWidget()->y() + (pluginWidget->topLevelWidget()->height() - 640)/2;
    timezone_x = timezone_x > 0 ? timezone_x : 0;
    timezone_y = timezone_y > 0 ? timezone_y : 0;

    m_timezone->move(timezone_x, timezone_y);
    m_timezone->show();

    QDBusReply<QVariant> tz = m_datetimeiproperties->call("Get", "org.freedesktop.timedate1", "Timezone");
    m_timezone->setMarkedTimeZoneSlot(getShowtz(tz.value().toString()));
}

bool DateTime::changezoneSlot(QString zone)
{
    QDBusMessage retDBus = m_datetimeiface->call("SetTimezone", zone, true);
    if (retDBus.type() == QDBusMessage::ErrorMessage) {
        return false;
    }
    return true;
}

void DateTime::timeFormatClickedSlot(bool flag, bool outChange)
{
    Q_UNUSED(outChange);
    if (!m_formatsettings) {
        qDebug()<<"org.ukui.control-center.panel.plugins not installed"<<endl;
        return;
    }
    fillTimeCombox(flag);
//    QStringList keys = m_formatsettings->keys();
//    if (keys.contains("hoursystem") && !outChange) {
//        if (flag == true) {
//            m_formatsettings->set(TIME_FORMAT_KEY, "24");
//        } else {
//            m_formatsettings->set(TIME_FORMAT_KEY, "12");
//        }
//    }
    //重置时间格式
    m_itimer->stop();
    m_itimer->start(1000);
}

QDBusMessage DateTime::rsyncWithNetworkSlot(bool status)
{
    return m_datetimeiface->call("SetNTP", status, true);
}

void DateTime::loadHour()
{
    if (!m_formatsettings) {
        qDebug()<<"org.ukui.control-center.panel.plugins not installed";
        return;
    }
    QStringList keys = m_formatsettings->keys();
    QString format;
    if (keys.contains("hoursystem")) {
        format = m_formatsettings->get(TIME_FORMAT_KEY).toString();
    }

    if (format == "24") {
        m_formTimeBtn->setChecked(true);
        fillTimeCombox(true);
    } else {
        m_formTimeBtn->setChecked(false);
        fillTimeCombox(false);
    }

    setCurrentTime();

    QDBusReply<QVariant> ret = m_datetimeiproperties->call("Get", "org.freedesktop.timedate1", "NTP");
    bool syncFlag = ret.value().toBool();

    if (syncFlag != false) {
        setNtpFrame(true);
        settimeFrame->setVisible(false);
        autoRadioButton->blockSignals(true);
        autoRadioButton->setChecked(true);
        m_checkedId = 0;
        autoRadioButton->blockSignals(false);

    } else {
        setNtpFrame(false);
        initSetTime();
        settimeFrame->setVisible(true);
        manualRadioButton->blockSignals(true);
        manualRadioButton->setChecked(true);
        m_checkedId = 1;
        manualRadioButton->blockSignals(false);
    }
}

QString  DateTime::getTimeAndWeek(const QDateTime timeZone)
{
    QString dateformat;
    if (m_formatsettings) {
        QStringList keys = m_formatsettings->keys();
        if(keys.contains("date")) {
            dateformat = m_formatsettings->get(DATE_KEY).toString();
        }
    }
    QString timeAndWeek;
    if ("cn" == dateformat) {
       timeAndWeek = timeZone.toString("yyyy/MM/dd ddd").replace("周","星期");
    } else {
       timeAndWeek = timeZone.toString("yyyy-MM-dd ddd");
    }
    return timeAndWeek;
}



void DateTime::setCurrentTime()
{
    initSetTime();
    current = QDateTime::currentDateTime();
    QString currentsecStr ;
    if (m_formTimeBtn->isChecked()) {
        currentsecStr = current.toString("hh : mm : ss");
    } else {
        if (QLocale::system().amText() == QString("上午") || QLocale::system().amText() == QString("སྔ་དྲོ་")) {
            currentsecStr = current.toString("AP hh: mm : ss");
        } else {
            currentsecStr = current.toString("hh: mm : ss AP");
        }
    }
    timeClockLable->setText(currentsecStr);
}

void DateTime::initConnect()
{
    connect(chgzonebtn, &QPushButton::clicked, this, [=](){
        changeZoneFlag = true;
        changezoneSlot();
    });

    connect(m_formTimeBtn, &KSwitchButton::stateChanged, this, [=](bool status) {
        timeFormatClickedSlot(status, false);
    });

    connect(m_timezone, &TimeZoneChooser::confirmed, this, [this] (const QString &timezone) {
        if (changeZoneFlag) {
            QString setTimezone = timezone;
            if (linkShanghaiTzList.contains(timezone)) {
                setTimezone = "Asia/Shanghai";
            }
            localZone = setTimezone;
            if (changezoneSlot(setTimezone)) {
                const QString locale = QLocale::system().name();
                localizedTimezone = m_zoneinfo->getLocalTimezoneName(timezone, locale);
                m_ukccIfc->call("setShowTimezone", timezone);
            }
            Common::buriedSettings(name(), QString("setTimezone"), QString("setting"), timezone);
        } else {
            addTimezone(timezone);
            Common::buriedSettings(name(), QString("addTimezone"), QString("setting"), timezone);
        }
        m_timezone->hide();
    });

    connect(m_itimer,SIGNAL(timeout()), this, SLOT(datetimeUpdateSlot()));

    connect(m_formatsettings, &QGSettings::changed, this, [=] (const QString &key) {
        if (key == "hoursystem") {
            QString value = m_formatsettings->get(TIME_FORMAT_KEY).toString();
            bool checked = (value == "24" ? true : false);
            m_formTimeBtn->blockSignals(true); //另一个地方监听执行了槽函数
            m_formTimeBtn->setChecked(checked);
            m_formTimeBtn->blockSignals(false);
        }
    });

    connect(dateEdit, &DateEdit::changeDate, this, [=]() {
        setTime();
    });

    connect(hourComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this, [=]() {
        setTime();
    });

    connect(minComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this, [=]() {
        setTime();
    });

    connect(secComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this, [=]() {
        setTime();
    });

}

QString DateTime::getLocalTimezoneName(QString timezone, QString locale)
{
    (void) setlocale(LC_ALL, QString(locale + ".UTF-8").toStdString().c_str());
    const QString local_name(dgettext(kTimezoneDomain,
                                      timezone.toStdString().c_str()));
    int index = local_name.lastIndexOf('/');
    if (index == -1) {
      // Some translations of locale name contains non-standard char.
      index = local_name.lastIndexOf("∕");
    }

    // Reset locale.
    (void) setlocale(LC_ALL, kDefaultLocale);

    return (index > -1) ? local_name.mid(index + 1) : local_name;
}

void DateTime::synctimeFormatSlot(bool status,bool outChange)
{
    Q_UNUSED(outChange);
    if (!m_formatsettings) {
        qDebug()<<"org.ukui.control-center.panel.plugins not installed"<<endl;
        return;
    }

    QDBusMessage retDBus = rsyncWithNetworkSlot(status);
    if (retDBus.type() == QDBusMessage::ErrorMessage) {
        timeGroupBtn->blockSignals(true);
        if (status) {
            manualRadioButton->setChecked(true);
            m_checkedId = 1;
        } else {
            autoRadioButton->setChecked(true);
            m_checkedId = 0;
        }
        timeGroupBtn->blockSignals(false);
        return;
    }
    if (status != false) {
        settimeFrame->setVisible(false);
        setNtpFrame(true);
        if (retDBus.type() == QDBusMessage::ReplyMessage) {
            if (syncThread) {
                syncThread->disconnect();
                syncThread->terminate();
                syncThread->quit();
                syncThread->wait();
                delete syncThread;
                syncThread = nullptr;
            }
            syncThread = new GetSyncRes(this);
            connect(syncThread, &GetSyncRes::finished, this, [=](){
                syncThread->deleteLater();
                syncThread = nullptr;
                manualRadioButton->setEnabled(true);
            });
            connect(syncThread, &GetSyncRes::inSync, this, [=](QPixmap pix) {
                syncNetworkRetLabel->setPixmap(pix);
            });
            connect(syncThread, &GetSyncRes::syncStatus, this, [=](bool status){
                manualRadioButton->setEnabled(true);
                if (status) {
                    syncNetworkRetLabel->setText(tr("  "));
                    syncRTC();
                } else {
                    syncNetworkRetLabel->setText(tr("Sync failed"));
                }
            });
            syncThread->start();
            manualRadioButton->setEnabled(false);
        } else {
            syncNetworkRetLabel->setText(tr("Sync failed"));
        }
    } else {
        initSetTime();
        settimeFrame->setVisible(true);
        setNtpFrame(false);
    }
}
/*同步硬件时钟*/
void DateTime::syncRTC()
{
    QDBusInterface * changeRTCinterface = new QDBusInterface("com.control.center.qt.systemdbus",
                                                             "/",
                                                             "com.control.center.interface",
                                                             QDBusConnection::systemBus());

    if (!changeRTCinterface->isValid()) {
        qCritical() << "Create Client Interface Failed When execute gpasswd: " << QDBusConnection::systemBus().lastError();
        return;
    }
    changeRTCinterface->call("changeRTC");
    delete changeRTCinterface;
    changeRTCinterface = nullptr;
}

bool DateTime::setNtpAddr(QString address)
{
    PolkitQt1::Authority::Result result;
    result = PolkitQt1::Authority::instance()->checkAuthorizationSync(
                "org.control.center.qt.systemdbus.action.ntp",
                PolkitQt1::UnixProcessSubject(QCoreApplication::applicationPid()),
                PolkitQt1::Authority::AllowUserInteraction);

    if (result == PolkitQt1::Authority::Yes) {
        QDBusInterface *setNtpAddrDbus = new QDBusInterface("com.control.center.qt.systemdbus",
                                                                 "/",
                                                                 "com.control.center.interface",
                                                                 QDBusConnection::systemBus());

        QDBusReply<bool> reply = setNtpAddrDbus->call("setNtpSerAddress", address);
        delete setNtpAddrDbus;
        setNtpAddrDbus = nullptr;
        return reply;
    }
    return false;
}

void DateTime::setNtpFrame(bool visiable)
{
    ntpFrame->setVisible(visiable);
    if (visiable && ntpCombox != nullptr) {
        ntpFrame_2->setVisible(ntpCombox->currentIndex() == ntpCombox->count() - 1);
    } else {
        ntpFrame_2->setVisible(visiable);
    }
}

void DateTime::initSetTime() {
    QDateTime m_time = QDateTime::currentDateTime();

    dateEdit->blockSignals(true);
    hourComboBox->blockSignals(true);
    minComboBox->blockSignals(true);
    secComboBox->blockSignals(true);

    if (!dateEdit->hasFocus())
        dateEdit->setDate(m_time.date());
    hourComboBox->setCurrentIndex(m_time.time().hour());
    minComboBox->setCurrentIndex(m_time.time().minute());
    secComboBox->setCurrentIndex(m_time.time().second());

    dateEdit->blockSignals(false);
    hourComboBox->blockSignals(false);
    minComboBox->blockSignals(false);
    secComboBox->blockSignals(false);
}

void DateTime::setTime() {
    QDate tmpdate(dateEdit->date());
    QTime tmptime(hourComboBox->currentIndex(), minComboBox->currentIndex(),secComboBox->currentIndex());
    QDateTime setdt(tmpdate,tmptime);

    m_datetimeiface->call("SetTime", QVariant::fromValue(setdt.toSecsSinceEpoch() * G_TIME_SPAN_SECOND), false, true);

}

bool DateTime::getSyncStatus() {
    return autoRadioButton->isChecked();
}

void DateTime::fillTimeCombox(bool format24)
{
    QString AMname = QLocale::system().amText();
    QString PMname = QLocale::system().pmText();

    hourComboBox->clear();
    if (!format24) {
        if (AMname == QString("上午") || AMname == QString("སྔ་དྲོ་")) {
            hourComboBox->addItem(AMname + QString::number(12));
            for (int i = 1 ; i <= 11; i++) {
                hourComboBox->addItem(AMname + QString::number(i));
            }
            hourComboBox->addItem(PMname + QString::number(12));
            for (int i = 1 ; i <= 11; i++) {
                hourComboBox->addItem(PMname + QString::number(i));
            }
        } else {
            hourComboBox->addItem(QString::number(12) + AMname);
            for (int i = 1 ; i <= 11; i++) {
                hourComboBox->addItem(QString::number(i) + AMname);
            }
            hourComboBox->addItem(QString::number(12) + PMname);
            for (int i = 1 ; i <= 11; i++) {
                hourComboBox->addItem(QString::number(i) + PMname);
            }
        }
    } else {
        for (int h = 0; h < 24; h++){
            hourComboBox->addItem(QString::number(h));
        }
    }
}

int DateTime::getRegionFormat()
{
    QString formats;
    QString language;
    QStringList result;
    unsigned int uid = getuid();
    QString objpath = "/org/freedesktop/Accounts/User"+QString::number(uid);
    QDBusInterface iproperty("org.freedesktop.Accounts",
                             objpath,
                             "org.freedesktop.DBus.Properties",
                             QDBusConnection::systemBus());
    QDBusReply<QMap<QString, QVariant> > reply = iproperty.call("GetAll", "org.freedesktop.Accounts.User");
    if (reply.isValid()){
        QMap<QString, QVariant> propertyMap;
        propertyMap = reply.value();
        if (propertyMap.keys().contains("FormatsLocale")) {
            formats = propertyMap.find("FormatsLocale").value().toString();
        }
        if(language.isEmpty() && propertyMap.keys().contains("Language")) {
            language = propertyMap.find("Language").value().toString();
        }
    } else {
        qDebug() << "reply failed";
    }
    result.append(formats);
    result.append(language);
    int formatIndex = result.at(0) == "zh_CN.UTF-8" ? 1 : 0;
    return formatIndex;
}

void DateTime::settingForIntel()
{
    chgzonebtn   -> setVisible(false);
    syncFrame    -> setVisible(false);
    settimeFrame -> setVisible(false);
    ntpFrame     -> setVisible(false);
    ntpFrame_2   -> setVisible(false);
    ui->TilleFrame->setVisible(false);
    ui->frame_7   ->setVisible(false);
    currentDateGroup->setFixedHeight(156);
    currentDateGroup->updateShape();
}

QString DateTime::getShowtz(QString setTz)
{
    QDBusReply<QString> showtz = m_ukccIfc->call("getShowTimezone");
    QString m_tz = showtz.value();
    if (!showtz.isValid() || showtz.value() != setTz) {
        //showtz 异常,重新设置
        if (!linkShanghaiTzList.contains(showtz) || m_tz.isEmpty()) {
            m_tz = setTz;
            m_ukccIfc->call("setShowTimezone", setTz);
        }
    }
    return m_tz;
}

void DateTime::initCurrentDate()
{
                       currentDateGroup   = new SettingGroup(this->pluginWidget);
    UkccFrame         *dateFrame          = new UkccFrame(currentDateGroup);
    Clock             *m_clock            = new Clock();
    UkccFrame         *dateRightFrame     = new UkccFrame(dateFrame);
                       timeClockLable     = new FixLabel(dateRightFrame);
    UkccFrame         *zoneFrame          = new UkccFrame(dateRightFrame);
                       dateLabel          = new FixLabel(zoneFrame);
                       chgzonebtn         = new FixButton(zoneFrame);
    //~ contents_path /Date/Set Time
                       syncFrame          = new UkccFrame(currentDateGroup, UkccFrame::BorderRadiusStyle::Around, true);
                       manualRadioButton  = new QRadioButton(syncFrame);
                       autoRadioButton    = new QRadioButton(syncFrame);
    FixLabel          *syncLabel          = new FixLabel(syncFrame);
    QSpacerItem       *iterm_radio        = new QSpacerItem(8, 24, QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed);
                       settimeFrame       = new UkccFrame(currentDateGroup, UkccFrame::BorderRadiusStyle::Around, true);
    FixLabel          *setLabel           = new FixLabel(settimeFrame);
    QSpacerItem       *iterm_1            = new QSpacerItem(8, 20, QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed);
                       dateEdit           = new DateEdit(settimeFrame);
    CustomCalendarWidget  *calendarWidget = new CustomCalendarWidget;
    QSpacerItem       *iterm_2            = new QSpacerItem(16, 20, QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed);
                       hourComboBox       = new QComboBox(settimeFrame);
                       minComboBox        = new QComboBox(settimeFrame);
                       secComboBox        = new QComboBox(settimeFrame);
    QLabel            *hourMinColonLabel  = new QLabel(":", settimeFrame);
    QLabel            *MinSecColonLabel   = new QLabel(":", settimeFrame);
                       ntpFrame           = new UkccFrame(currentDateGroup, UkccFrame::BorderRadiusStyle::Around, true);
                       ntpFrame_2         = new UkccFrame(currentDateGroup, UkccFrame::BorderRadiusStyle::Around, true);
    QHBoxLayout       *dateLayout         = new QHBoxLayout(dateFrame);
    QHBoxLayout       *zoneLayout         = new QHBoxLayout(zoneFrame);
    QHBoxLayout       *syncLayout         = new QHBoxLayout(syncFrame);
    QHBoxLayout       *settimeLayout      = new QHBoxLayout(settimeFrame);
    QVBoxLayout       *dateRightLayout    = new QVBoxLayout(dateRightFrame);

    currentDateGroup -> addWidget(dateFrame);
    currentDateGroup -> addWidget(syncFrame);
    currentDateGroup -> addWidget(settimeFrame);
    currentDateGroup -> addWidget(ntpFrame);
    currentDateGroup -> addWidget(ntpFrame_2);
    dateLayout       -> addWidget(m_clock);
    dateLayout       -> addWidget(dateRightFrame);
    dateLayout       -> addStretch();
    dateRightLayout  -> addWidget(timeClockLable);
    dateRightLayout  -> addWidget(zoneFrame);
    zoneLayout       -> addWidget(dateLabel);
    zoneLayout       -> addWidget(chgzonebtn);
    zoneLayout       -> addStretch();
    syncLayout       -> addWidget(syncLabel);
    syncLayout       -> addWidget(manualRadioButton);
    syncLayout       -> addSpacerItem(iterm_radio);
    syncLayout       -> addWidget(autoRadioButton);
    syncLayout       -> addWidget(syncNetworkRetLabel);
    syncLayout       -> addStretch();
    settimeLayout    -> addWidget(setLabel);
    settimeLayout    -> addSpacerItem(iterm_1);
    settimeLayout    -> addWidget(dateEdit);
    settimeLayout    -> addSpacerItem(iterm_2);
    settimeLayout    -> addWidget(hourComboBox);
    settimeLayout    -> addWidget(hourMinColonLabel);
    settimeLayout    -> addWidget(minComboBox);
    settimeLayout    -> addWidget(MinSecColonLabel);
    settimeLayout    -> addWidget(secComboBox);
    settimeLayout    -> addStretch();

    dateFrame->setFixedHeight(156);
    dateRightFrame->setFixedHeight(102);
    chgzonebtn->setMinimumWidth(120);
    chgzonebtn->setMaximumWidth(300);
    dateLayout->setContentsMargins(16, 0, 0, 0);
    settimeLayout->setContentsMargins(16, 0, 0, 0);
    dateRightLayout->setMargin(0);
    dateLayout->setSpacing(26);
    zoneLayout->setMargin(0);
    zoneLayout->setSpacing(16);
    settimeLayout->setSpacing(0);
    syncLayout->setContentsMargins(16, 0, 0, 0);
    syncLayout->setSpacing(26);
    syncLabel->setFixedWidth(119);
    //~ contents_path /Date/Set Time
    syncLabel->setText(tr("Set Time"));
    //~ contents_path /Date/Set Date Manually
    setLabel->setText(tr("Set Date Manually"));
    setLabel->setFixedWidth(137);
    hourComboBox->setFixedWidth(100);
    minComboBox->setFixedWidth(64);
    secComboBox->setFixedWidth(64);
    hourMinColonLabel->setFixedWidth(16);
    MinSecColonLabel->setFixedWidth(16);
    hourMinColonLabel->setAlignment(Qt::AlignCenter);
    MinSecColonLabel->setAlignment(Qt::AlignCenter);
    dateEdit->setCalendarPopup(true);
    dateEdit->setCalendarWidget(calendarWidget);

    ui->currentDateLayout->addWidget(currentDateGroup);
    return;
}
